package com.hoshino.momochi.util;

public class LuaScript {
    /**
     * KEYS[1] 当前 登录成功后 创建的 TOKEN
     * ARGV[1] 当前 用户 ID
     * ARGV[2] 默认 TOKEN 存活时间
     *
     * @return 存入 key-value => token-ID 返回 LuaScript
     */
    public static String setTokenAndReturnLuaScript() {
        return "local token" +
                "\n token=KEYS[1]" +
                "\n if token then" +
                "\n redis.call('set',token,ARGV[1])" +
                "\n return redis.call('expire',token,ARGV[2])" +
                "\n end" +
                "\n return nil;";
    }

    /**
     * 如果 id 存在 则需要删除 id 对应的 token 如果 不存在 则 添加
     * KEYS[1] Map
     * ARGV[1] user_id
     * ARGV[2] token
     * ARGV[3] 过期时间
     *
     * @return
     */
    public static String mapUserIdToTokenScript() {
        return "local a" +
                "\n a=redis.call('hget', KEYS[1], ARGV[1])" +
                "\n if a then" +
                "\n redis.call('del',a)" + // 删除已有token
                "\n end" +
                "\n redis.call('set', ARGV[2], ARGV[1])" +// 设置新的token
                "\n redis.call('expire', ARGV[2], ARGV[3])" + // 过期时间
                "\n redis.call('hset',KEYS[1], ARGV[1], ARGV[2])"; // 更新 Map
    }

    /**
     * 限流脚本
     * 调用的时候不超过阈值，则直接返回并执行计算器自加。
     *
     * @return lua脚本
     */
    public static String buildLuaScript() {
        return "local c" +
                "\nc = redis.call('get',KEYS[1])" +
                "\nif c and tonumber(c) > tonumber(ARGV[1]) then" +
                "\nreturn c;" +
                "\nend" +
                "\nc = redis.call('incr',KEYS[1])" +
                "\nif tonumber(c) == 1 then" +
                "\nredis.call('expire',KEYS[1],ARGV[2])" +
                "\nend" +
                "\nreturn c;";
    }

    /**
     * 首先 判断 TOKEN 是否存在
     * 存在 则 重置 TOKEN 持续时间
     * 不存在 则 返回 nil 空
     *
     * @return
     */
    public static String geTokenToCheckLuaScript() {
        return "local token" +
                "\n token=KEYS[1]" +
                "\n local kiruya" +
                "\n kiruya=redis.call('get',token)" +
                "\n if kiruya then" +
                "\n redis.call('expire',token,ARGV[1])" +
                "\n return tonumber(kiruya)" +
                "\n end" +
                "\n return nil";
    }

    /**
     * 缓存 MYSQL 数据库数据，如有修改MYSQL操作 则 单独对某一页 再进行更新操作即可。
     * KEYS 为 要保存的字符串 列表， ARGV[1] 传入 列表长度
     *
     * @param front 键值前缀
     * @return lua 脚本
     */
    public static String doCacheFrontScript(String front) {
        return "local front=ARGV[2]" +
                "\n for i=1,ARGV[1] do" +
                "\n local key=front..i" +
                "\n redis.call('set', key, KEYS[i])" +
                "\n end" +
                "\n return 1";
    }

    public static String getCacheScript() {
        return "local a" +
                "\n a=redis.call('get',KEYS[1])" +
                "\n if a then" +
                "\n return a" +
                "\n end" +
                "\n return nil";
    }

    public static String setListJson() {
        return "local a" +
                "\n a=KEYS[1]" +
                "\n redis.call('set',a,ARGV[1])" +
                "\n return 1";
    }

    /**
     * 保存消息 KEYS[1] 为消息接收者 ， ARGV[1] 则是MessageDTO
     *
     * @return Lua
     */
    public static String saveMessageScript() {
        return "local a" +
                "\n a=redis.call('RPUSH',KEYS[1],ARGV[1])";
    }

    /**
     * 拉取消息
     */
    public static String pullMessageScript() {
        return "local a" +
                "\n a=redis.call('keys', KEYS[1])" +
                "\n if a then" +
                "\n local l=redis.call('LRANGE',KEYS[1],0,-1)" +
                "\n redis.call('del',KEYS[1])" +
                "\n return l" +
                "\n end" +
                "\n return nil";
    }

    /**
     * 缓存用户名
     *
     * @return
     */
    public static String cacheUsernameScript() {
        return "for i=1,ARGV[1] do" +
                "\n redis.call('SADD',ARGV[2],KEYS[i])" +
                "\n end";
    }

    /**
     * 判断用户名是否已经存在
     *
     * @return
     */
    public static String checkUsernameScript() {
        return "local a" +
                "\n a=redis.call('SISMEMBER',KEYS[1],ARGV[1])" +
                "\n return a";
    }

    /**
     * 如果存在KEYS[1] 则 删除 KEYS[1]
     *
     * @return
     */
    public static String deleteScript() {
        return "local a" +
                "\n a=redis.call('get',KEYS[1])" +
                "\n if a then" +
                "\n redis.call('del',KEYS[1])" +
                "\n end";
    }

    public static String cacheBlogScript() {
        return "redis.call('set',KEYS[1],ARGV[1])";
    }

    public static String getCacheBlogScript() {
        return "return redis.call('get',KEYS[1]);";
    }

    public static String delUserLoginStaScript() {
        return "local a" +
                "\n a=redis.call('get', KEYS[1])" +
                "\n if a then" +
                "\n redis.call('del',KEYS[1])" +
                "\n end";
    }

    public static String addMailToCode() {
        return "redis.call('set',KEYS[1],ARGV[1])" +
                "\n redis.call('expire',KEYS[1], ARGV[2])";
    }

    public static String getMailCode() {
        return "local a" +
                "\n a=redis.call('get',KEYS[1])" +
                "\n if a then" +
                "\n return a" +
                "\n end" +
                "\n return nil";
    }
}
